#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <mysql.h>
#include <sys/types.h>
#include <time.h>

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/uio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

#define QUERY_LEN 1023
#define LKNAME_LEN 1023

#define HOST "127.0.0.1"
#define USER "root"
#define PASSWORD ""
#define DB "test"
#define PORT 3306
#define LK_PATH "."

int Injectionfilter(char *sWhere)
{
	return 0;
}

/*
 * Returns 1 if a directory has been created,
 * 2 if it already existed, and 0 on failure.
 */
int build(char *path, mode_t omode)
{
	struct stat sb;
	mode_t numask, oumask;
	int first, last, retval;
	char *p;

	p = path;
	oumask = 0;
	retval = 1;
	if (p[0] == '/')		/* Skip leading '/'. */
		++p;
	for (first = 1, last = 0; !last ; ++p) {
		if (p[0] == '\0')
			last = 1;
		else if (p[0] != '/')
			continue;
		*p = '\0';
		if (!last && p[1] == '\0')
			last = 1;
		if (first) {
			/*
			 * POSIX 1003.2:
			 * For each dir operand that does not name an existing
			 * directory, effects equivalent to those caused by the
			 * following command shall occcur:
			 *
			 * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
			 *	mkdir [-m mode] dir
			 *
			 * We change the user's umask and then restore it,
			 * instead of doing chmod's.
			 */
			oumask = umask(0);
			numask = oumask & ~(S_IWUSR | S_IXUSR);
			(void)umask(numask);
			first = 0;
		}
		if (last)
			(void)umask(oumask);
		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
			if (errno == EEXIST || errno == EISDIR) {
				if (stat(path, &sb) < 0) {
					fprintf(stderr, "%s", path);
					retval = 0;
					break;
				} else if (!S_ISDIR(sb.st_mode)) {
					if (last)
						errno = EEXIST;
					else
						errno = ENOTDIR;
					fprintf(stderr, "%s", path);
					retval = 0;
					break;
				}
				if (last)
					retval = 2;
			} else {
				fprintf(stderr, "%s", path);
				retval = 0;
				break;
			}
		}
		if (!last)
			*p = '/';
	}
	if (!first && !last)
		(void)umask(oumask);
	return (retval);
}

int LinkMail(const char * sWhere)
{
	int retval;
	MYSQL *pMysql;

	pMysql = (MYSQL*)malloc(sizeof(MYSQL));
	if (pMysql == NULL)
		return (-1);

	if (!mysql_real_connect(pMysql, HOST, USER, PASSWORD, DB, PORT, NULL, 0)) {
		fprintf(stderr, "connect failed: %s\n", mysql_error(pMysql));
		mysql_close(pMysql);
		free(pMysql);
		pMysql = NULL;
		return (-2);
	}

	char sQuery[1024] = "";
	snprintf(sQuery, 1024, "select `time` ,`from` ,`path` from vmime where %s", 
			sWhere);

	if (mysql_query(pMysql, sQuery) != 0) {
		fprintf(stderr, "query failed: %s\n", mysql_error(pMysql));
		mysql_close(pMysql);
		free(pMysql);
		pMysql = NULL;
		return (-3);
	}

	MYSQL_RES *pResult = mysql_store_result(pMysql);
	const int icount = mysql_num_rows(pResult);
	if(icount <= 0)
	{
		fprintf(stdout, "no result\n");
		free(pMysql);
		pMysql = NULL;
		return (1);
	}	
	char* asFiles = (char *)malloc(icount*LKNAME_LEN);
	memset(asFiles, 0, icount*LKNAME_LEN);

	MYSQL_ROW pRow;
	int i = 0;
	printf("<Result>\n");
	while((pRow = mysql_fetch_row(pResult))!=NULL && i<icount)
	{
		printf("\t%s - %s\n", pRow[0], pRow[1]);
		if(pRow[2])
			strncpy(asFiles+(i++)*LKNAME_LEN, pRow[2], LKNAME_LEN);
	}
	printf("<\\Result>\n\n");

	int flag = 0;
	printf("please choose wether to make links\n1.link\n2.not link\n");
	scanf("%d", &flag);
	if(flag!=1) {
		free(asFiles);
		free(pMysql);
		pMysql = NULL;
		return 0;
	}

	printf("\nlinks:\n");

	time_t t0 = time(NULL);
	struct tm *t1=localtime(&t0);

	char sLkName[LKNAME_LEN] = "";
	char sLkPath[LKNAME_LEN] = "";
	snprintf(sLkPath, LKNAME_LEN, "%s/%d%d%d/%d%d%d/", LK_PATH, t1->tm_year+1900, t1->tm_mon+1, t1->tm_mday,
		t1->tm_hour, t1->tm_min, t1->tm_sec);
	char sTmp[LKNAME_LEN] = "";
	strncpy(sTmp, sLkPath, LKNAME_LEN);
	build(sTmp, S_IRWXU | S_IRWXG);

	for(i=0; i<icount; i++)
	{
		snprintf(sLkName, LKNAME_LEN, "%s%d", sLkPath, i);
		printf("%s -> %s\n", sLkName, asFiles+i*LKNAME_LEN);
		symlink(asFiles+i*LKNAME_LEN, sLkName);
	}
	free(asFiles);
	mysql_free_result(pResult);
	mysql_close(pMysql);
	free(pMysql);
	pMysql = NULL;
	return 0;
}
